package com.tokenmaster.aitrade.common.account;

import java.text.SimpleDateFormat;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONObject;
import com.tokenmaster.aitrade.common.system.MnsComponent;
import com.tokenmaster.aitrade.data.SystemDB;

public class Account {

	private Logger logger = Logger.getLogger(this.getClass());

	private SystemDB systemDB = SystemDB.getInstance();

	private MnsComponent mnsComponent = MnsComponent.getInstance();

	private long unixtime = 0;

	private String accountName = "";

	private String accountID = "";

	private String coinName = "";

	private SimpleDateFormat sformat = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");

	public Account(String accountName, String accountID, String coinName) {

		this.accountName = accountName;
		this.accountID = accountID;
		this.coinName = coinName;

	}

	public long getUnixtime() {
		return unixtime;
	}

	public void setUnixtime(long unixtime) {
		this.unixtime = unixtime;
	}

	public double getAvg_price() {
		return systemDB.getAvgPriceFromAccount(accountName, coinName);
	}

	/**
	 * 获取仓位
	 * 
	 * @return
	 */
	public double getPosition() {
		double cash = systemDB.getAccount(accountName, "USDT");
		double coinNum = systemDB.getAccount(accountName, coinName);
		double avg_price = systemDB.getAvgPriceFromAccount(accountName, coinName);

		double position = avg_price * coinNum / (avg_price * coinNum + cash);

		return position;
	}

	/**
	 * 获取仓位对应的花费
	 * 
	 * @return
	 */
	public double getPositionCost(double position) {
		double cash = systemDB.getAccount(accountName, "USDT");
		double coinNum = systemDB.getAccount(accountName, coinName);
		double avg_price = systemDB.getAvgPriceFromAccount(accountName, coinName);

		return (avg_price * coinNum + cash) * position;
	}

	public double getTotalAsset(double price) {

		double cash = systemDB.getAccount(accountName, "USDT");
		double coinNum = systemDB.getAccount(accountName, coinName);
		return price * coinNum + cash;

	}

	public boolean buyCoinByMoney(double price, double cost, long unixtime) {

		double cash = systemDB.getAccount(accountName, "USDT");

		if (cash < cost || cash < 100) {
			return false;
		}

		double amount = cost / price;

		pushMessage(accountID, (coinName + "_USDT").toLowerCase(), "buy", price, amount, unixtime);

		logger.info(sformat.format(unixtime) + " 买入:" + coinName + " 数量:" + amount + " 价格:" + price);

		return true;

	}

	public boolean buyCoinByPosition(double price, double position, long unixtime) {

		double cash = systemDB.getAccount(accountName, "USDT");

		if (cash < 5000) {
			return false;
		}

		// 买币花费
		double cost = cash * position;
		
		// 如果剩余现金小于5000美金,一并买进
		if (cash - cost < 5000)
			cost = cash;
		
		double amount = cost / price;

		pushMessage(accountID, (coinName + "_USDT").toLowerCase(), "buy", price, amount, unixtime);

		logger.info(sformat.format(unixtime) + " 买入:" + coinName + " 数量:" + amount + " 价格:" + price);

		return true;

	}

	/**
	 * 按仓位卖出
	 * 
	 * @param price
	 * @param amount
	 * @param unixtime
	 * @return
	 */
	public boolean sellCoinByPosition(double price, double position, long unixtime) {

		boolean result = false;

		double coinNum = systemDB.getAccount(accountName, coinName);

		if (coinNum < 0.01) {
			return false;
		}

		double amount = coinNum * position;

		// 剩余币值不足5000 ,一并卖出
		if ((coinNum - amount) * price < 5000) {
			amount = coinNum;
		}

		pushMessage(accountID, (coinName + "_USDT").toLowerCase(), "sell", price, amount, unixtime);
		
		logger.info(sformat.format(unixtime) + " 卖出:" + coinName + " 数量:" + amount + " 价格:" + price);

		return result;
	}

	public boolean sellCoinByMoney(double price, double cost, long unixtime) {

		boolean result = false;

		double coinNum = systemDB.getAccount(accountName, coinName);

		double amount = cost / price;

		if (coinNum < 0.1) {
			return false;
		}

		// 剩余币值不足5000 ,一并卖出
		if ((coinNum - amount) * price < 5000) {
			amount = coinNum;
		}

		pushMessage(accountID, (coinName + "_USDT").toLowerCase(), "sell", price, amount, unixtime);

		logger.info(sformat.format(unixtime) + " 卖出:" + coinName + " 数量:" + amount + " 价格:" + price);

		return result;
	}

	public boolean sellCoin(double price, double amount, long unixtime) {

		boolean result = false;

		double coinNum = systemDB.getAccount(accountName, coinName);

		if (coinNum < 0.01 || amount > coinNum) {
			return false;
		}

		pushMessage(accountID, (coinName + "_USDT").toLowerCase(), "sell", price, amount, unixtime);
		
		logger.info(sformat.format(unixtime) + " 卖出:" + coinName + " 数量:" + amount + " 价格:" + price);

		return result;
	}

	public boolean sellAllCoin(double price, long unixtime) {

		boolean result = false;

		double coinNum = systemDB.getAccount(accountName, coinName);

		if (coinNum < 0.01) {
			return false;
		}

		double amount = coinNum;

		pushMessage(accountID, (coinName + "_USDT").toLowerCase(), "sell", price, amount, unixtime);

		logger.info(sformat.format(unixtime) + " 卖出:" + coinName + " 数量:" + amount + " 价格:" + price);

		return result;
	}

	private void pushMessage(String robotId, String symbol, String businessType, double price, double amount,
			long unixtime) {

		JSONObject jsonObject = new JSONObject();

		jsonObject.put("symbol", symbol);
		jsonObject.put("robotid", robotId);
		jsonObject.put("type", businessType);
		jsonObject.put("price", price);
		jsonObject.put("amount", amount);
		jsonObject.put("unixtime", unixtime);

		try {
			mnsComponent.sendMessage(jsonObject.toJSONString());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
